<template>
  <div class="r-container">
    <input type="file" ref="upload" accept=".json" @change="executorpListchange" id="r_file_executor"
      style="display: none;">
    <div style="display:flex">
      <div class='r-opreation' style="flex:1">
        <el-tag>总数：{{ tableData.length }}</el-tag>
        <el-button style="margin-left:40px" type="primary" @click="uploadJson" round title="初始化文件">
          <el-icon style="margin-right: 4px;">
            <Document />
          </el-icon>
          初始化文件
        </el-button>
        <el-button type="primary" @click="downloadFile" round title="下载文件">
          <el-icon style="margin-right: 4px;">
            <DocumentChecked />
          </el-icon>
          下载文件
        </el-button>
        <el-button type="primary" @click="showJson" round title="查看json">
          <el-icon style="margin-right: 4px;">
            <DocumentCopy />
          </el-icon>
          查看json
        </el-button>

        <el-button v-show="!onSerachR" icon="Search" circle @click="onSerachR = true"></el-button>

        <el-button v-show="onSerachR" class="search">
          <el-icon>
            <Search />
          </el-icon>
          <input v-model="searchR" placeholder="请输入角色名称">
          <el-icon @click="onSerachR = false; searchR = ''">
            <Close />
          </el-icon>
        </el-button>
      </div>
      <div class='r-opreation' style="flex:1;margin-left: 20px;">
        <el-tag style="margin-right: 20px;">选中{{ rpNum }}</el-tag>
        <el-tag v-if="rpNull" type="danger">未上传rolepermission.json</el-tag>
        <el-tag v-if="!rpNull" type="danger">{{ fileName }}</el-tag>
      </div>
    </div>
    <div class="edit" ref="edit">
      <el-table :default-sort="{ prop: 'id', order: 'ascending' }" highlight-current-row height='100%'
        empty-text='数据为空，请上传role.json'
        :data="rTableData.filter(data => !searchR || data.name.toLowerCase().includes(searchR.toLowerCase()) || data.sign.toLowerCase().includes(searchR.toLowerCase()))"
        ref="rMultipleTable" tooltip-effect="dark" style="width: 100%">

        <el-table-column prop="sign" label="sign" show-overflow-tooltip width="80">
        </el-table-column>
        <el-table-column prop="name" label="name" show-overflow-tooltip>
        </el-table-column>
        <el-table-column prop="id" label="id">
        </el-table-column>
        <el-table-column label="操作" width="100">
          <template #default="scope">
            <el-button @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div style="height: 100%;width: 2px;background-color: #eee;margin-left: 30px;"></div>
      <div style="width: 50%;height: 100%;display: flex;flex-direction: column;">
        <div style="font-size: 14px;font-weight: bold;color: #999;margin: 7px 30px;">角色权限</div>
        <el-table :default-sort="{ prop: 'id', order: 'ascending' }" v-loading="loading" height='100%'
          @select='selectPdata' empty-text='数据为空，请上传rolepermission.json' :data="pTableData" ref="multipleTable"
          tooltip-effect="dark" style="width: 100%;margin-left: 20px;flex: 1;">
          <el-table-column type="selection" width="55">
          </el-table-column>
          <el-table-column prop="sign" label="sign" show-overflow-tooltip width="80">
          </el-table-column>
          <el-table-column prop="name" label="name" show-overflow-tooltip>
          </el-table-column>
          <el-table-column prop="id" label="id">
          </el-table-column>
        </el-table>
      </div>
    </div>
    <el-dialog title="json" v-model="jsonDialogShow" width="600px" center>
      <textarea class="json-txt" :value='jsonInfo'>
  </textarea>
    </el-dialog>
  </div>
</template>

<script>
import store from "../store"
import { ElMessage, ElLoading } from 'element-plus'
import { Search, Close, Document, DocumentChecked, DocumentCopy } from '@element-plus/icons-vue'

export default {
  name: "RPManager",
  components: {
    Search,
    Close,
    Document,
    DocumentChecked,
    DocumentCopy
  },
  data() {
    return {
      jsonInfo: '',
      jsonDialogShow: false,
      fileName: 'rolepermission.json',
      deleteDialogVisible: true,
      tableData: [],
      rTableData: [],
      pTableData: [],
      rpTableData: [],//选中项
      pTableDataMap: new Map(),
      roleIdMap: new Map(),
      editType: 'add',
      form: {
        name: '',
        sign: '',
        id: '',
        index: -1
      },
      multipleSelection: [],
      searchR: '',
      onSerachR: false,
      editRoleId: 0,//当前编辑的id
      editRoleIndex: 0,//当前编辑的角色索引
      editRow: {},//当前编辑的角色索引
      rpNum: 0,
      rpNull: false,
      loading: false
    }
  },
  store,
  methods: {
    selectPdata(selection, row) {
      if (selection.indexOf(row) === -1) {
        if (!this.tableData[this.roleIdMap.get(this.editRoleId)]) {
          return
        }
        for (let i = this.tableData[this.roleIdMap.get(this.editRoleId)].permission.length - 1; i >= 0; i--) {
          if (this.tableData[this.roleIdMap.get(this.editRoleId)].permission[i].id === row.id) {
            this.tableData[this.roleIdMap.get(this.editRoleId)].permission.splice(i, 1)
          }
        }
      } else {
        if (this.tableData[this.roleIdMap.get(this.editRoleId)] === undefined) {
          this.tableData.push({
            roleId: this.editRoleId + "",
            permission: []
          })
          this.roleIdMap.set(this.editRoleId, this.tableData.length - 1)
        }
        this.tableData[this.roleIdMap.get(this.editRoleId)].permission = selection
      }
      this.save()

      setTimeout(() => {
        this.handleEdit(this.editRoleIndex, this.editRow)
      }, 50);
    },
    resetForm() {
      this.form = {
        name: '',
        sign: '',
        id: '',
        index: -1
      }
    },
    removeSelect() {
      let selection = this.$refs.multipleTable.selection
      selection.sort(function (a, b) {
        return a.index - b.index;
      })
      for (let i = selection.length - 1; i >= 0; i--) {
        this.tableData.splice(selection[i].index, 1)
      }
      this.save()
    },
    downloadFile() {
      if (!this.tableData) {
        ElMessage.error('未初始化');
        return
      }
      const loading = ElLoading.service({
        lock: true,
        text: '正在整理导出...',
        background: 'rgba(0, 0, 0, 0.7)'
      });

      function fakeClick(obj) {
        var ev = document.createEvent("MouseEvents");
        ev.initMouseEvent(
          "click",
          true,
          false,
          window,
          0,
          0,
          0,
          0,
          0,
          false,
          false,
          false,
          false,
          0,
          null
        );
        obj.dispatchEvent(ev);
      }

      function exportRaw(name, data) {
        var urlObject = window.URL || window.webkitURL || window;
        var export_blob = new Blob([data]);
        var save_link = document.createElementNS(
          "http://www.w3.org/1999/xhtml",
          "a"
        );
        save_link.href = urlObject.createObjectURL(export_blob);
        save_link.download = name;
        fakeClick(save_link);
        setTimeout(() => {
          loading.close();
        }, 500);
      }
      let outJson = JSON.parse(JSON.stringify(this.tableData))
      outJson.sort(function (a, b) {
        return parseInt(a.roleId.replace('role', '')) - parseInt(b.roleId.replace('role', ''));
      })
      //整理数据
      for (let i = 0; i < outJson.length; i++) {
        outJson[i].permission.sort(function (a, b) {
          return parseInt(a.id.replace('permission', '')) - parseInt(b.id.replace('permission', ''));
        })
        outJson[i].permission = outJson[i].permission.map(x => { return { id: x.id } }) // 生成数组
      }
      exportRaw(
        this.fileName,
        JSON.stringify(outJson, null, 4)
      );
    },
    cancelEdit() {
      this.editType = 'add'
      this.form = {
        name: '',
        sign: '',
        id: '',
        index: -1
      }
    },
    save() {
      sessionStorage.setItem('rpList', JSON.stringify(this.tableData))
      sessionStorage.setItem('rpFileName', this.fileName)
    },
    addRole() {
      if (this.form.index && this.form.index > -1) {
        this.$set(this.tableData, this.form.index, {
          name: this.form.name,
          sign: this.form.sign,
          id: this.form.id,
        })
      } else {
        if (!this.form.id) {
          ElMessage.error('id必填');
          return
        }
        if (!this.form.name) {
          ElMessage.error('name必填');
          return
        }

        if (!this.form.sign) {
          ElMessage.error('sign必填');
          return
        }

        for (let i = 0; i < this.tableData.length; i++) {
          if (this.tableData[i].id == this.form.id) {
            ElMessage.error('id已存在');
            return
          } else if (this.tableData[i].name == this.form.name) {
            ElMessage.error('name已存在');
            return
          }
          else if (this.tableData[i].sign == this.form.sign) {
            ElMessage.error('sign已存在');
            return
          }
        }
        this.tableData.push({
          name: this.form.name,
          sign: this.form.sign,
          id: this.form.id,
        })
      }

      this.save();
    },
    uploadJson() {
      var inputObj = document.querySelector(
        "#r_file_executor"
      );
      inputObj.click();
    },
    executorpListchange() {
      var files = document.querySelector("#r_file_executor").files
      let file = files[0]
      if (file.name.indexOf(".json") != file.name.length - 5) {
        ElMessage.error('不支持的文件格式');
        return;
      }

      var reader = new FileReader(); //新建一个FileReader
      reader.readAsText(file, "UTF-8"); //读取文件
      reader.onload = (evt) => {
        let roles = JSON.parse(evt.target.result)
        if (roles instanceof Array) {
          if (roles.length == 0 || roles[0].roleId === undefined) {
            ElMessage.error('格式有误');
            return
          }
          this.tableData = roles
          for (let i = 0; i < roles.length; i++) {
            this.roleIdMap.set(roles[i].roleId, i)
          }
        } else {
          ElMessage.error('格式有误');
        }
        this.fileName = file.name
        this.save();
        document.querySelector("#r_file_executor").value = ''

        this.handleEdit(0, this.rTableData[0])
        this.rpNull = false
        this.fileName = file.name
      }
    },
    handleEdit(index, row) {
      if (!row.id) {
        return
      }
      this.$refs.rMultipleTable.setCurrentRow(row);
      this.editRoleId = row.id
      this.editRoleIndex = index
      this.editRow = row
      this.$refs.multipleTable.clearSelection();

      let rpTableData = []
      if (this.roleIdMap.get(row.id) !== undefined) {
        rpTableData = this.tableData[this.roleIdMap.get(row.id)].permission
        this.rpNum = this.tableData[this.roleIdMap.get(row.id)].permission.length
      } else {
        this.rpNum = 0
      }
      this.rpTableData.splice(0, this.rpTableData.length)
      setTimeout(() => {
        for (let i = 0; i < rpTableData.length; i++) {
          ((i) => {
            let index = this.pTableDataMap.get(rpTableData[i].id)
            if (index !== undefined) {
              this.rpTableData.push(this.pTableData[index])
              this.$refs.multipleTable.toggleRowSelection(this.pTableData[index], true);
            }
          })(i)
        }
      }, 50);

    },
    handleDelete(index) {
      this.deleteDialogVisible = false
      this.tableData.splice(index, 1)
      this.save()
    },
    fakeClick(obj) {
      var ev = document.createEvent("MouseEvents");
      ev.initMouseEvent(
        "click",
        true,
        false,
        window,
        0,
        0,
        0,
        0,
        0,
        false,
        false,
        false,
        false,
        0,
        null
      );
      obj.dispatchEvent(ev);
    },
    showJson() {
      if (!this.tableData) {
        ElMessage.error('未初始化');
        return
      }
      const loading = ElLoading.service({
        lock: true,
        text: '正在整理导出...',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      let outJson = JSON.parse(JSON.stringify(this.tableData))
      outJson.sort(function (a, b) {
        return parseInt(a.roleId.replace('role', '')) - parseInt(b.roleId.replace('role', ''));
      })
      //整理数据
      for (let i = 0; i < outJson.length; i++) {
        outJson[i].permission.sort(function (a, b) {
          return parseInt(a.id.replace('permission', '')) - parseInt(b.id.replace('permission', ''));
        })
        outJson[i].permission = outJson[i].permission.map(x => { return { id: x.id } }) // 生成数组
      }
      loading.close()

      this.jsonInfo = JSON.stringify(outJson, null, 4)
      this.jsonDialogShow = true
    }
  },
  computed: {

  },
  mounted() {
    this.pTableDataMap.clear()
    this.tableData.splice(0, this.tableData.length)
    this.rTableData.splice(0, this.rTableData.length)
    this.pTableData.splice(0, this.pTableData.length)
    if (sessionStorage.getItem('rpList')) {
      this.tableData = JSON.parse(sessionStorage.getItem('rpList'))
      this.fileName = sessionStorage.getItem('rpFileName')
      for (let i = 0; i < this.tableData.length; i++) {
        this.roleIdMap.set(this.tableData[i].roleId, i)
      }
    } else {
      this.rpNull = true
    }

    if (sessionStorage.getItem('rList')) {
      this.rTableData = JSON.parse(sessionStorage.getItem('rList'))
      setTimeout(() => {
        this.handleEdit(0, this.rTableData[0])
      }, 50);
    }

    if (sessionStorage.getItem('pList')) {
      this.pTableData = JSON.parse(sessionStorage.getItem('pList'))
      for (let i = 0; i < this.pTableData.length; i++) {
        this.pTableDataMap.set(this.pTableData[i].id, i)
      }
    }

  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.r-container {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
}

.json-txt {
  resize: none;
  width: 100%;
  height: 600px;
  border: none;
  outline: none;
}

.json-txt:hover {
  border: none;
  outline: none;
}

.r-container .r-opreation {
  text-align: left;
  margin-bottom: 10px;
}

.r-container .r-opreation .search {
  margin-left: 10px;
  display: inline-flex;
  align-items: center;
  padding: 0 14px;
  border-radius: 40px;
}

.r-container .r-opreation .search input {
  border: none;
  outline: none;
  background-color: transparent;
  margin-left: 4px;
}

.r-container .r-opreation .search i {
  color: rgba(143, 143, 143, 0.933);
}

.r-container .r-opreation .search .el-icon-close {
  cursor: pointer;
}

.r-container .r-opreation .search .el-icon-close:hover {
  color: #f56c6c;
}

.r-container .r-opreation .search:hover {
  border: 1px #bcdeff solid;
}

.r-container .edit {
  display: flex;
  height: 10px;
  flex: 1;
}

.r-container .edit .el-table {
  flex: 1;
}

.r-container .edit .el-form {
  width: 300px;
  margin-left: 40px;
}
</style>
